package org.vaadin.nf4v.ext.runtime.afternav;

import org.vaadin.nf4v.core.navigation.NavigationRequest;
import org.vaadin.nf4v.core.navigation.event.NavigationListener;
import org.vaadin.nf4v.core.navigation.event.NavigationState;
import org.vaadin.nf4v.ext.config.afternav.ExtAfterNavUtil;

/**
 * Listener provides runtime support for @AfterNavigation annotation.
 * It notifies all pages, containing methods annotated with @AfterNavigation
 * with AFTER_NAVIGATION events.
 *
 * Such methods may have:
 * 1. no parameters
 * 2. NavigationRequest as parameter
 * 3. Params (the same as request.params()) as parameter
 *
 * By default pages instances with annotated methods will be reused for request change requests.
 * It may be changed by specifying @AfterNavigation(reuseInstance = false).
 *
 * Listener must be registered with PAGE_PARAMETERS_CHANGE and AFTER_NAVIGATION events.
 */
public class AfterNavigationListener implements NavigationListener {

    @Override
    public void onNavigation(NavigationRequest request) {
        // phase one - preserving current page instance for parameter change request
        if (request.isParametersChangeRequest() && request.getState() == NavigationState.PAGE_PARAMETERS_CHANGE &&
                ExtAfterNavUtil.isAfterNavigationListenerMethodAllowInstanceReuse(request)) {
            // preserving current page instance
            request.getTarget().setRequirePageInstanceCreation(false);
        }

        // phase two - invoking notification method on after navigation state
        if (request.getState() == NavigationState.AFTER_NAVIGATION &&
                ExtAfterNavUtil.hasAfterNavigationListenerMethod(request)) {
            ExtAfterNavUtil.notifyAfterNavigation(request);
        }
    }
}
